package com.zb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.CodeConstant;
import com.zb.entity.*;
import com.zb.enums.SystemSetEnum;
import com.zb.extend.CodeExtend;
import com.zb.extend.CodeLogExtend;
import com.zb.mapper.ZjCodeMapper;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.utils.CodeUtil;
import com.zb.utils.TransactionUtil;
import com.zb.utils.ZbDateUtil;
import com.zb.utils.ZbManager;
import com.zb.view.ViewGoods;
import com.zb.vo.*;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

/**
 * <p>
 * 编码表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-08-23
 */
@Service
public class ZjCodeServiceImpl extends ServiceImpl<ZjCodeMapper, ZjCode> implements ZjCodeService {
    @Resource
    private ZjCodeMapper codeMapper;
    @Resource(name = "asyncServiceExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private PlatformTransactionManager transactionManager;
    @Resource
    private ZjCodeService codeService;
    @Resource
    private ZjCode02Service code02Service;
    @Resource
    private ZjCodeInfo02Service codeInfo02Service;
    @Resource
    private ZjCodeInfo03Service codeInfo03Service;
    @Resource
    private ZjCodeInfo04Service codeInfo04Service;
    @Resource
    private ZjCodeInfo05Service codeInfo05Service;
    @Resource
    private ZjCode03Service code03Service;
    @Resource
    private ZjCode04Service code04Service;
    @Resource
    private ZjCode05Service code05Service;
    @Resource
    private ZjCodeInfoService codeInfoService;
    @Resource
    private ZjCodeLogService codeLogService;
    @Resource
    private ZjCodeLog02Service codeLog02Service;
    @Resource
    private ZjCodeLog03Service codeLog03Service;
    @Resource
    private ZjCodeLog04Service codeLog04Service;
    @Resource
    private ZjCodeLog05Service codeLog05Service;
    @Resource
    private ZjCodeBatchService codeBatchService;
    @Resource
    private ZjCodeGoodsChangeLogService codeGoodsChangeLogService;
    @Resource
    private ZjProductService productService;
    @Resource
    private ZjSpareService spareService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private ZjCodeUserRegisterService codeUserRegisterService;
    @Resource
    private ViewGoodsService viewGoodsService;

    /**
     * 集合执行数量大小
     */
    private static int EXCUTE_SIZE = 5000;

    // 新增编码
    @Override
    public List<ZjCode> save(AccounLoginInfo loginInfo, CodeVo codeVo, CodeParamInfo codeParamInfo) {
        Integer warrantyDay = null != codeVo.getWarrantStartTime() && null != codeVo.getWarrantEndTime() ? (int) ZbDateUtil.getDays(codeVo.getWarrantEndTime(), codeVo.getWarrantStartTime()) : codeVo.getWarrantyDay();
        Date startTime = null;
        if (null != codeParamInfo.getCodeUserRegister()){
            startTime = null != codeVo.getWarrantStartTime()? codeVo.getWarrantStartTime() : new Date();
        }
        Date endTime = null;
        if (null != startTime) {
            endTime = DateUtils.addDays(startTime, warrantyDay);
        }
        codeVo.setWarrantStartTime(startTime);
        codeVo.setWarrantEndTime(endTime);

        Integer status = CodeConstant.CODE_STATUS_1;
        Integer storeStatus = CodeConstant.STORE_STATUS_1;
        boolean activa = false;
        boolean codeRegister = false;
        Date activaTime = null;
        if (null != codeParamInfo.getCodeUserRegister()) {
            status = new Date().before(endTime)? CodeConstant.CODE_STATUS_2 : CodeConstant.CODE_STATUS_3;
            storeStatus = CodeConstant.STORE_STATUS_5;
            activa = true;
            codeRegister = true;
            activaTime = startTime;
        }
        if (codeParamInfo.isInStore()) storeStatus = CodeConstant.STORE_STATUS_2;
        if (codeParamInfo.isOutStore()) storeStatus = CodeConstant.STORE_STATUS_4;
        ZjCode code = null;
        ZjCodeInfo codeInfo = null;
        ZjCodeLog log = null;
        ZjCodeUserRegister userRegister = null;
        List<CodeDataVo> codeDatasVoList = new ArrayList<>();
        CodeDataVo vo = new CodeDataVo();
        int i = 0;
        int size = 0;
        String logName =  "新建编码";
        String logContent = "新建编码";
        if (codeParamInfo.isCodeFromOrder()) {
            logName =  "系统工单报单创建新编码";
            logContent = "系统工单报单创建新编码";
            if (codeParamInfo.isInStore()) {
                logName =  "工单配件入库创建临时编码";
                logContent = "工单配件入库创建临时编码";
            }
            if (codeParamInfo.isOutStore()) {
                logName =  "工单配件出库创建临时编码";
                logContent = "工单配件出库创建临时编码";
            }
        }
        List<ZjCode> codeResult = new ArrayList<>();
        // 工单商品编码对象
        List<OrderGoodsCodeVo> goodsCodes = new ArrayList<>();
        while (i < codeVo.getQty()) {
            size++;
            // 编码
            code = new ZjCode();
            code.setId(IdWorker.getId());
            code.setCustAccId(loginInfo.getCustAccId());
            code.setBatchId(codeParamInfo.getCodeBatchId());
            code.setBatchGoodsId(codeVo.getBatchGoodsId());
            code.setType(codeParamInfo.getType());
            code.setGoodsId(codeVo.getGoodsId());
            code.setGoodsSpecId(codeVo.getGoodsSpecId());
            code.setSecurityCode((StringUtils.isBlank(codeParamInfo.getCodePrefix())? "" : codeParamInfo.getCodePrefix()) + CodeUtil.generatorCode(codeParamInfo.getCodeRule(), codeParamInfo.getDate()));
            code.setStoreCode((StringUtils.isBlank(codeParamInfo.getStorehousePrefix())? "" : codeParamInfo.getStorehousePrefix()) + CodeUtil.generatorCode(codeParamInfo.getStorehouseRule(), codeParamInfo.getDate()));
            code.setOutStoreWarranty(false);
            code.setWarrantyDay(warrantyDay);
            code.setWarrantyStartTime(startTime);
            code.setWarrantyEndTime(endTime);
            code.setStatus(status);
            code.setArchived(false);
            code.setStoreId(null == codeVo.getStoreId()? 0L : codeVo.getStoreId());
            code.setStorePositionId(null == codeVo.getStoreIdPositionId()? 0L : codeVo.getStoreIdPositionId());
            code.setStoreStatus(storeStatus);
            code.setActiva(activa);
            code.setOutStoreActiva(false);
            code.setActivaTime(activaTime);
            code.setCodeSource(codeParamInfo.getCodeSource());
            code.setNetworkId(0L);
            code.setNetwork("");
            code.setDisabled(false);
            code.setCreateEmpId(loginInfo.getId());
            code.setCreateEmp(loginInfo.getName());
            code.setUpdateEmpId(loginInfo.getId());
            code.setUpdateEmp(loginInfo.getName());
            // 编码信息
            codeInfo = new ZjCodeInfo();
            codeInfo.setId(code.getId());
            codeInfo.setCustAccId(loginInfo.getCustAccId());
            codeInfo.setRegister(codeRegister);
            codeInfo.setRegisterTime(activaTime);
            codeInfo.setSelectNum(0);
            codeInfo.setInboundCode(codeParamInfo.isInStore()? codeParamInfo.getOutInBoundNo() : "");
            codeInfo.setOutboundCode(codeParamInfo.isOutStore()? codeParamInfo.getOutInBoundNo() : "");
            // 编码操作记录
            log = new ZjCodeLog();
            log.setId(IdWorker.getId());
            log.setCustAccId(loginInfo.getCustAccId());
            log.setCodeId(code.getId());
            log.setType(CodeConstant.CODE_LOG_TYPE_1);
            log.setName(logName);
            log.setContent(logContent);
            log.setCreateEmpId(loginInfo.getId());
            log.setCreateEmp(loginInfo.getName());

            if (null != codeParamInfo.getCodeUserRegister()) {
                userRegister = new ZjCodeUserRegister();
                BeanUtils.copyProperties(codeParamInfo.getCodeUserRegister(), userRegister);
                userRegister.setId(code.getId());
                userRegister.setCustAccId(loginInfo.getCustAccId());
                vo.getRegisters().add(userRegister);
            }
            extractedData(CodeConstant.tableType(code.getId()), vo, code, codeInfo, log);
            i++;
            if (i >= codeVo.getQty() && size < EXCUTE_SIZE) {
                codeDatasVoList.add(vo);
            }
            if (size == EXCUTE_SIZE) {
                codeDatasVoList.add(vo);
                size = 0;
                if (i < codeVo.getQty()) {
                    vo = new CodeDataVo();
                }
            }
            if (!codeParamInfo.isSyncCommitTransaction()) codeResult.add(code);
            goodsCodes.add(new OrderGoodsCodeVo(code.getId(), code.getSecurityCode()));
        }
        codeVo.setGoodsCodes(goodsCodes);

        if (codeParamInfo.isSyncCommitTransaction()) {
            CountDownLatch countDownLatch = new CountDownLatch(codeDatasVoList.size());
            codeDatasVoList.forEach(t -> {
                threadPoolTaskExecutor.execute(() -> {
                    executeSave(countDownLatch, t.getCodes(), t.getInfos(), t.getLogs());
                    code02Service.save(countDownLatch, t.getCode02s(), t.getInfo02s(), t.getLog02s());
                    code03Service.save(countDownLatch, t.getCode03s(), t.getInfo03s(), t.getLog03s());
                    code04Service.save(countDownLatch, t.getCode04s(), t.getInfo04s(), t.getLog04s());
                    code05Service.save(countDownLatch, t.getCode05s(), t.getInfo05s(), t.getLog05s());
                });
            });
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
            }
        } else {
            codeDatasVoList.forEach(t -> {
                executeSave(t.getCodes(), t.getInfos(), t.getLogs());
                code02Service.save(t.getCode02s(), t.getInfo02s(), t.getLog02s());
                code03Service.save(t.getCode03s(), t.getInfo03s(), t.getLog03s());
                code04Service.save(t.getCode04s(), t.getInfo04s(), t.getLog04s());
                code05Service.save(t.getCode05s(), t.getInfo05s(), t.getLog05s());
                if (null != t.getRegisters() && !t.getRegisters().isEmpty()) {
                    codeUserRegisterService.saveBatch(t.getRegisters());
                }
            });
        }
        return codeResult;
    }

    // 保存工单导入的编码信息
    @Override
    public void saveOrderExcelImportCode(List<ZjCode> addCodeList, List<ZjCode> updateCodeList, List<ZjCodeInfo> addCodeInfoList, List<ZjCodeInfo> updateCodeInfoList, List<ZjCodeLog> codeLogList) {
        if (CollectionUtil.isNotEmpty(addCodeList)) {
            List<ZjCode> codes = new ArrayList<>();
            List<ZjCode02> code02s = new ArrayList<>();
            List<ZjCode03> code03s = new ArrayList<>();
            List<ZjCode04> code04s = new ArrayList<>();
            List<ZjCode05> code05s = new ArrayList<>();
            for (ZjCode code : addCodeList) {
                switch (CodeConstant.tableType(code.getId())) {
                    case 0:
                        codes.add(code);
                        continue;
                    case 1:
                        code02s.add(new ZjCode02(code));
                        continue;
                    case 2:
                        code03s.add(new ZjCode03(code));
                        continue;
                    case 3:
                        code04s.add(new ZjCode04(code));
                        continue;
                    case 4:
                        code05s.add(new ZjCode05(code));
                }
            }
            if (CollectionUtil.isNotEmpty(codes)) this.saveBatch(codes);
            if (CollectionUtil.isNotEmpty(code02s)) code02Service.saveBatch(code02s);
            if (CollectionUtil.isNotEmpty(code03s)) code03Service.saveBatch(code03s);
            if (CollectionUtil.isNotEmpty(code04s)) code04Service.saveBatch(code04s);
            if (CollectionUtil.isNotEmpty(code05s)) code05Service.saveBatch(code05s);
        }
        if (CollectionUtil.isNotEmpty(updateCodeList)) {
            List<ZjCode> codes = new ArrayList<>();
            List<ZjCode02> code02s = new ArrayList<>();
            List<ZjCode03> code03s = new ArrayList<>();
            List<ZjCode04> code04s = new ArrayList<>();
            List<ZjCode05> code05s = new ArrayList<>();
            for (ZjCode code : updateCodeList) {
                switch (CodeConstant.tableType(code.getId())) {
                    case 0:
                        codes.add(code);
                        continue;
                    case 1:
                        code02s.add(new ZjCode02(code));
                        continue;
                    case 2:
                        code03s.add(new ZjCode03(code));
                        continue;
                    case 3:
                        code04s.add(new ZjCode04(code));
                        continue;
                    case 4:
                        code05s.add(new ZjCode05(code));
                }
            }
            if (CollectionUtil.isNotEmpty(codes)) this.updateBatchById(codes);
            if (CollectionUtil.isNotEmpty(code02s)) code02Service.updateBatchById(code02s);
            if (CollectionUtil.isNotEmpty(code03s)) code03Service.updateBatchById(code03s);
            if (CollectionUtil.isNotEmpty(code04s)) code04Service.updateBatchById(code04s);
            if (CollectionUtil.isNotEmpty(code05s)) code05Service.updateBatchById(code05s);
        }
        codeInfoService.saveInbatch(addCodeInfoList, updateCodeInfoList);
        codeLogService.saveInBatch(codeLogList);
    }

    /**
     * 根据规则封装数据
     * @param index
     * @param code
     * @param codeInfo
     * @param codeLog
     */
    private static void extractedData(long index, CodeDataVo vo, ZjCode code, ZjCodeInfo codeInfo, ZjCodeLog codeLog) {
        if (index == 0) {
            vo.getCodes().add(code);
            vo.getInfos().add(codeInfo);
            vo.getLogs().add(codeLog);
            return;
        }
        if (index == 1) {
            vo.getCode02s().add(new ZjCode02(code));
            vo.getInfo02s().add(new ZjCodeInfo02(codeInfo));
            vo.getLog02s().add(new ZjCodeLog02(codeLog));
            return;
        }
        if (index == 2) {
            vo.getCode03s().add(new ZjCode03(code));
            vo.getInfo03s().add(new ZjCodeInfo03(codeInfo));
            vo.getLog03s().add(new ZjCodeLog03(codeLog));
            return;
        }
        if (index == 3) {
            vo.getCode04s().add(new ZjCode04(code));
            vo.getInfo04s().add(new ZjCodeInfo04(codeInfo));
            vo.getLog04s().add(new ZjCodeLog04(codeLog));
            return;
        }
        if (index == 4) {
            vo.getCode05s().add(new ZjCode05(code));
            vo.getInfo05s().add(new ZjCodeInfo05(codeInfo));
            vo.getLog05s().add(new ZjCodeLog05(codeLog));
        }
    }

    /**
     * 执行保存编码
     * @param countDownLatch
     * @param codeList
     * @param codeInfos
     * @param codeLogs
     */
    private void executeSave(CountDownLatch countDownLatch, List<ZjCode> codeList, List<ZjCodeInfo> codeInfos, List<ZjCodeLog> codeLogs) {
        TransactionStatus status = transactionManager.getTransaction(TransactionUtil.transactionDefinition());
        try {
            codeService.saveBatch(codeList);
            codeInfoService.saveBatch(codeInfos);
            codeLogService.saveBatch(codeLogs);
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
        } finally {
            countDownLatch.countDown();
        }
    }

    /**
     * 执行保存编码
     * @param codeList
     * @param codeInfos
     * @param codeLogs
     */
    private void executeSave(List<ZjCode> codeList, List<ZjCodeInfo> codeInfos, List<ZjCodeLog> codeLogs) {
        codeService.saveBatch(codeList);
        codeInfoService.saveBatch(codeInfos);
        codeLogService.saveBatch(codeLogs);
    }

    @Override
    public void updateById(int tableType, ZjCode code) {
        if (tableType == 0) this.updateById(code);
        if (tableType == 1) code02Service.updateById(new ZjCode02(code));
        if (tableType == 2) code03Service.updateById(new ZjCode03(code));
        if (tableType == 3) code04Service.updateById(new ZjCode04(code));
        if (tableType == 5) code05Service.updateById(new ZjCode05(code));
    }


    // 查询编码列表
    @Override
    public Map<String, Object> getList(Long custAccId, CodeListSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        // 获取商品ID
        List<Long> goodsIds = null;
        if (null != selectVo.getBrandId() || null != selectVo.getTypeId() || StringUtils.isNotBlank(selectVo.getGoods())) {
            GoodsSelect goodsSelect = new GoodsSelect(custAccId, selectVo.getBrandId(), selectVo.getTypeId(), selectVo.getGoods());
            goodsSelect.setPage(selectVo.getPage());
            goodsSelect.setLimit(selectVo.getLimit());

            if (null == selectVo.getType()) {
                goodsIds = goodsService.pageGetGoodsIds(goodsSelect);
                if (goodsIds.isEmpty()) goodsIds.add(-1L);
            }
            if (null != selectVo.getType() && 1 == selectVo.getType()) {
                goodsIds = productService.pageGetIds(goodsSelect);
                if (goodsIds.isEmpty()) goodsIds.add(-1L);
            }
            if (null != selectVo.getType() && 2 == selectVo.getType()) {
                goodsIds = spareService.pageGetIds(goodsSelect);
                if (goodsIds.isEmpty()) goodsIds.add(-1L);
            }
        }
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), getListCount(custAccId, goodsIds, selectVo), getListData(custAccId, goodsIds, selectVo));
    }

    // 查询编码列表数据
    @Override
    public List<CodeListVo> getListData(Long custAccId, List<Long> goodsIds, CodeListSelectVo selectVo) {
        List<CodeListVo> codeList =  codeMapper.getList(custAccId, goodsIds, selectVo);
        List<Long> goodIds = codeList.stream().map(CodeListVo::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = codeList.stream().map(CodeListVo::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodIds, goodsSpecIds);
        List<ZjCodeBatch> codeBatches = codeBatchService.getByIds(new ArrayList<>(codeList.stream().map(CodeListVo::getBatchId).collect(Collectors.toSet())));
        List<ZjCodeUserRegister> userRegisters = codeUserRegisterService.getByIds(codeList.stream().map(CodeListVo::getId).toList());
        for (CodeListVo t : codeList) {
            codeBatches.stream().filter(vo -> Objects.equals(vo.getId(), t.getBatchId())).findFirst().ifPresent(batch -> {
                t.setBatchName(batch.getName());
                t.setBatchCode(batch.getCode());
            });
            userRegisters.stream().filter(user -> Objects.equals(user.getId(), t.getId())).findFirst().ifPresent(userRegister -> {
                t.setUsername(userRegister.getName());
                t.setPhone(userRegister.getPhone());
            });
            viewGoodsList.stream().filter(f -> Objects.equals(f.getGoodsType(), t.getType()) && Objects.equals(f.getId(), t.getGoodsId())
                    && Objects.equals(f.getSpecId(), t.getGoodsSpecId())).findFirst().ifPresent(goodsSpecView -> {
                t.setBrand(goodsSpecView.getBrand());
                t.setGoodsName(goodsSpecView.getName());
                t.setGoodsModel(goodsSpecView.getModel());
                t.setGoodsType(goodsSpecView.getType());
                t.setGoodsSpecName(goodsSpecView.getSpecName());
            });
        }
        return codeList;
    }

    // 查询编码列表总记录数
    @Override
    public long getListCount(Long custAccId, List<Long> goodsIds, CodeListSelectVo selectVo) {
        return codeMapper.getListCont(custAccId, goodsIds, selectVo);
    }


    // 批量激活编码
    @Override
    @Transactional
    public void updateBatchActiveByIds(AccounLoginInfo loginInfo, List<CodeParamVo> codeParamVos) {
        for (CodeParamVo codeParamVo : codeParamVos) {
            Assert.isTrue(null != codeParamVo.getTableType(), "[tableType]的类型参数不能为空");
        }
        Assert.isTrue(null != codeParamVos && !codeParamVos.isEmpty(), "请传入需要激活的编码信息");
        // 查询已激活的编码
        List<String> activCodes = codeMapper.getActivCodeByIds(codeParamVos.stream().map(CodeParamVo::getId).toList());
        Assert.isTrue(null == activCodes || activCodes.isEmpty(), "编码已激活，不可重复激活[" +String.join("、", activCodes)+ "]");

        ZjCode code = null;
        ZjCodeLog codeLog = null;
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        for (CodeParamVo vo : codeParamVos) {
            code = new ZjCode();
            code.setId(vo.getId());
            code.setActiva(true);
            code.setActivaTime(new Date());
            code.setUpdateEmpId(loginInfo.getId());
            code.setUpdateEmp(loginInfo.getName());

            codeLog =  new ZjCodeLog();
            codeLog.setId(IdWorker.getId());
            codeLog.setCustAccId(loginInfo.getCustAccId());
            codeLog.setCodeId(code.getId());
            codeLog.setType(CodeConstant.CODE_LOG_TYPE_1);
            codeLog.setName("手动激活编码");
            codeLog.setContent("手动激活编码");
            codeLog.setCreateEmpId(loginInfo.getId());
            codeLog.setCreateEmp(loginInfo.getName());
            codeLog.setGmtCreate(new Date());
            if (vo.getTableType() == 1) {
                codes.add(code);
                codeLogs.add(codeLog);
                continue;
            }
            if (vo.getTableType() == 2) {
                code02s.add(new ZjCode02(code));
                codeLog02s.add(new ZjCodeLog02(codeLog));
                continue;
            }
            if (vo.getTableType() == 3) {
                code03s.add(new ZjCode03(code));
                codeLog03s.add(new ZjCodeLog03(codeLog));
                continue;
            }
            if (vo.getTableType() == 4) {
                code04s.add(new ZjCode04(code));
                codeLog04s.add(new ZjCodeLog04(codeLog));
                continue;
            }
            if (vo.getTableType() == 5) {
                code05s.add(new ZjCode05(code));
                codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (!codes.isEmpty()) {
            this.updateBatchById(codes);
            codeLogService.saveBatch(codeLogs);
        }
        code02Service.updateBatchActivCodeByIds(code02s, codeLog02s);
        code03Service.updateBatchActivCodeByIds(code03s, codeLog03s);
        code04Service.updateBatchActivCodeByIds(code04s, codeLog04s);
        code05Service.updateBatchActivCodeByIds(code05s, codeLog05s);
    }

    // 批量删除编码
    @Override
    public void deleteBatchByIds(List<CodeParamVo> codeParamVos) {
        if (null == codeParamVos || codeParamVos.isEmpty()) {
            return;
        }
        List<Long> codeIds = codeParamVos.stream().filter(vo -> vo.getTableType() == 1).map(CodeParamVo::getId).toList();
        List<Long> codeId02s = codeParamVos.stream().filter(vo -> vo.getTableType() == 2).map(CodeParamVo::getId).toList();
        List<Long> codeId03s = codeParamVos.stream().filter(vo -> vo.getTableType() == 3).map(CodeParamVo::getId).toList();
        List<Long> codeId04s = codeParamVos.stream().filter(vo -> vo.getTableType() == 4).map(CodeParamVo::getId).toList();
        List<Long> codeId05s = codeParamVos.stream().filter(vo -> vo.getTableType() == 5).map(CodeParamVo::getId).toList();
        if (!codeIds.isEmpty()) {
            this.removeByIds(codeIds);
            codeInfoService.removeByIds(codeIds);
            codeLogService.deleteByCodeIds(codeIds);
        }
        code02Service.deleteBatchByIds(codeId02s);
        code03Service.deleteBatchByIds(codeId03s);
        code04Service.deleteBatchByIds(codeId04s);
        code05Service.deleteBatchByIds(codeId05s);
        codeGoodsChangeLogService.deleteByCodeIds(codeParamVos.stream().map(CodeParamVo::getId).toList());
    }

    // 更改编码商品信息
    @Override
    @Transactional
    public void codeGoodsBindingChange(AccounLoginInfo loginInfo, CodeGoodsChangeVo goodsChangeVo) {
        // 查询编码是否登记
        Assert.isTrue(!codeInfoService.existCodeRegisById(goodsChangeVo.getId()), "该编码已与用户关联并登记质保，不可变更");
        CodeExtend codeExtend = getInfoById(goodsChangeVo.getId());
        ViewGoods viewGoods = viewGoodsService.getByGoodsTypeAndGoodsIdAndGoodsSpecId(codeExtend.getType(), goodsChangeVo.getGoodsId(), goodsChangeVo.getGoodsSpecId());
        Assert.notNull(viewGoods, "更改编码的商品类型不合法，或更改的商品信息不存在");

        ZjCode code = new ZjCode();
        code.setId(goodsChangeVo.getId());
        code.setType(goodsChangeVo.getType());
        code.setGoodsId(goodsChangeVo.getGoodsId());
        code.setGoodsSpecId(goodsChangeVo.getGoodsSpecId());
        code.setGmtUpdate(new Date());
        code.setUpdateEmpId(loginInfo.getId());
        code.setUpdateEmp(loginInfo.getName());

        ZjCodeLog codeLog = new CodeLogExtend(loginInfo, CodeConstant.CODE_LOG_TYPE_1, code.getId(), "编码商品绑定信息变更", "");
        int tableType = CodeConstant.tableType(goodsChangeVo.getId());
        if (tableType == 0) {
            ZjCode oldCode = this.getById(goodsChangeVo.getId());
            this.updateById(code);
            codeLogService.save(codeLog);
            codeGoodsChangeLogService.save(loginInfo, goodsChangeVo.getId(), oldCode.getType(), oldCode.getGoodsId(), oldCode.getGoodsSpecId(), goodsChangeVo.getRemark());
            return;
        }
        if (tableType == 1) {
            ZjCode02 oldCode = code02Service.getById(goodsChangeVo.getId());
            code02Service.updateById(new ZjCode02(code));
            codeLog02Service.save(new ZjCodeLog02(codeLog));
            codeGoodsChangeLogService.save(loginInfo, goodsChangeVo.getId(), oldCode.getType(), oldCode.getGoodsId(), oldCode.getGoodsSpecId(), goodsChangeVo.getRemark());
            return;
        }
        if (tableType == 2) {
            ZjCode03 oldCode = code03Service.getById(goodsChangeVo.getId());
            code03Service.updateById(new ZjCode03(code));
            codeLog03Service.save(new ZjCodeLog03(codeLog));
            codeGoodsChangeLogService.save(loginInfo, goodsChangeVo.getId(), oldCode.getType(), oldCode.getGoodsId(), oldCode.getGoodsSpecId(), goodsChangeVo.getRemark());
            return;
        }
        if (tableType == 3) {
            ZjCode04 oldCode = code04Service.getById(goodsChangeVo.getId());
            code04Service.updateById(new ZjCode04(code));
            codeLog04Service.save(new ZjCodeLog04(codeLog));
            codeGoodsChangeLogService.save(loginInfo, goodsChangeVo.getId(), oldCode.getType(), oldCode.getGoodsId(), oldCode.getGoodsSpecId(), goodsChangeVo.getRemark());
            return;
        }
        if (tableType == 4) {
            ZjCode05 oldCode = code05Service.getById(goodsChangeVo.getId());
            code05Service.updateById(new ZjCode05(code));
            codeLog05Service.save(new ZjCodeLog05(codeLog));
            codeGoodsChangeLogService.save(loginInfo, goodsChangeVo.getId(), oldCode.getType(), oldCode.getGoodsId(), oldCode.getGoodsSpecId(), goodsChangeVo.getRemark());
        }
    }

    // 根据编码ID获取信息
    @Override
    public CodeExtend getInfoById(Long id) {
        return codeMapper.getDetailById(id);
    }

    // 编码登记时更新编码信息
    @Override
    public void updateCodeInfoByRegister(AccounLoginInfo loginInfo, Long id, String logName, String logContent) {
        CodeExtend zjCode = codeService.getInfoById(id);
        ZjCode code = new ZjCode();
        code.setId(id);

        if (!zjCode.getActiva()) {
            code.setActiva(true);
            code.setActivaTime(new Date());
        }

        if (null == zjCode.getWarrantyStartTime() && null == zjCode.getWarrantyEndTime()) {
            code.setWarrantyStartTime(new Date());
            code.setWarrantyEndTime(DateUtils.addDays(code.getWarrantyStartTime(), zjCode.getWarrantyDay()));
        }
        code.setStatus(new Date().after(code.getWarrantyEndTime())? CodeConstant.CODE_STATUS_3 : CodeConstant.CODE_STATUS_2);
        code.setStoreStatus(zjCode.getStoreStatus() == CodeConstant.STORE_STATUS_5? zjCode.getStoreStatus() : CodeConstant.STORE_STATUS_5);
        code.setUpdateEmpId(loginInfo.getId());
        code.setUpdateEmp(loginInfo.getName());

        ZjCodeInfo info = null;
        // 查询是否登记
        if (!codeInfoService.existCodeRegisById(code.getId())) {
            info = new ZjCodeInfo();
            info.setId(code.getId());
            info.setRegister(true);
            info.setRegisterTime(new Date());
        }

        ZjCodeLog codeLog = new CodeLogExtend(loginInfo, CodeConstant.CODE_LOG_TYPE_1, code.getId(), logName, logContent);
        if (zjCode.getTableType() == 1) {
            this.updateById(code);
            if (null != info) codeInfoService.updateById(info);
            codeLogService.save(codeLog);
            return;
        }
        if (zjCode.getTableType() == 2) {
            code02Service.updateById(new ZjCode02(code));
            if (null != info) codeInfo02Service.updateById(new ZjCodeInfo02(info));
            codeLog02Service.save(new ZjCodeLog02(codeLog));
            return;
        }
        if (zjCode.getTableType() == 3) {
            code03Service.updateById(new ZjCode03(code));
            if (null != info) codeInfo03Service.updateById(new ZjCodeInfo03(info));
            codeLog03Service.save(new ZjCodeLog03(codeLog));
            return;
        }
        if (zjCode.getTableType() == 4) {
            code04Service.updateById(new ZjCode04(code));
            if (null != info) codeInfo04Service.updateById(new ZjCodeInfo04(info));
            codeLog04Service.save(new ZjCodeLog04(codeLog));
            return;
        }
        if (zjCode.getTableType() == 5) {
            code05Service.updateById(new ZjCode05(code));
            if (null != info) codeInfo05Service.updateById(new ZjCodeInfo05(info));
            codeLog05Service.save(new ZjCodeLog05(codeLog));
        }
    }

    // 根据编码ID获取表类型
    @Override
    public Integer getTableTypeById(Long id) {
        return codeMapper.getTableTypeById(id);
    }

    // 分页获取批次ID
    @Override
    public List<Long> pageGetBatchIds(Long custAccId, List<Long> goodsIds, Long page, Long limit) {
        return codeMapper.pageGetBatchIds(custAccId, goodsIds, page, limit);
    }

    // 根据批次ID查询编码激活数量
    @Override
    public List<CodeBatchListVo> getActivaCountByBatchIds(List<Long> batchIdList) {
        if (null == batchIdList || batchIdList.isEmpty()) {
            return new ArrayList<>();
        }
        return codeMapper.getActivaCountByBatchIds(batchIdList);
    }

    // 根据批次ID获取编码列表
    @Override
    public Map<String, Object> getCodeList(Long batchId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        List<CodeExtend> codes = codeMapper.getCodeList(batchId, pageUtil);
        List<Long> ids = codes.stream().map(ZjCode::getId).toList();
        List<Long> goodsIds = codes.stream().map(ZjCode::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = codes.stream().map(ZjCode::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);
        List<ZjCodeInfo> codeInfos = codeInfoService.getRegistTimeByIds(ids);
        List<BatchCodeListVo> voList = codes.stream().map(code -> {
            BatchCodeListVo vo = new BatchCodeListVo();
            BeanUtils.copyProperties(code, vo);
            vo.setRegisterTime(codeInfos.stream().filter(info -> Objects.equals(vo.getId(), info.getId())).map(ZjCodeInfo::getRegisterTime).findFirst().orElse(null));
            viewGoodsList.stream().filter(f -> Objects.equals(f.getGoodsType(), code.getType()) && Objects.equals(f.getId(), code.getGoodsId()) && Objects.equals(f.getSpecId(), code.getGoodsSpecId()))
                    .findFirst().ifPresent(specView -> {
                        vo.setBrand(specView.getBrand());
                        vo.setGoodsModel(specView.getModel());
                        vo.setGoodsName(specView.getName());
                        vo.setGoodsSpecName(specView.getSpecName());
                    });
            return vo;
        }).toList();
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), codeMapper.getCodeListCount(batchId), voList);
    }

    // 根据编码批次ID查询检查是否编码有关联信息
    @Override
    public void checkCodeRelationInfoForDeleteByBatchIds(List<Long> codeBatchIds) {
        List<CodeRelateoinInfoVo> relateoinInfoVos = codeMapper.checkCodeRelationInfoForDeleteByBatchIds(codeBatchIds);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code02Service.checkCodeRelationInfoForDeleteByBatchIds(codeBatchIds);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code03Service.checkCodeRelationInfoForDeleteByBatchIds(codeBatchIds);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code04Service.checkCodeRelationInfoForDeleteByBatchIds(codeBatchIds);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code05Service.checkCodeRelationInfoForDeleteByBatchIds(codeBatchIds);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        List<Long> codeIds = codeMapper.getRelationWorkByBatchIds(codeBatchIds);
        if (CollectionUtil.isNotEmpty(codeIds)) {
            relateoinInfoVos = codeMapper.checkCodeRelationInfoByIds(codeIds);
            List<String> codes = relateoinInfoVos.stream().filter(CodeRelateoinInfoVo::getActiva).map(CodeRelateoinInfoVo::getSecurityCode).toList();
            Assert.isTrue(codes.isEmpty(), "编码[" + String.join("、", codes) + "]已关联工单商品，不可删除");
        }
    }

    private void checkCodeRelationIinfoTipMessage(List<CodeRelateoinInfoVo> relateoinInfoVos) {
        if (CollectionUtil.isEmpty(relateoinInfoVos)) {
            return;
        }
        List<String> codes = relateoinInfoVos.stream().filter(vo -> Objects.equals(2, vo.getStoreStatus()) || Objects.equals(3, vo.getStoreStatus())).map(CodeRelateoinInfoVo::getSecurityCode).toList();
        Assert.isTrue(codes.isEmpty(), "关联的编码[" + String.join("、", codes) + "]已入库或出库，不可删除");
        codes = relateoinInfoVos.stream().filter(CodeRelateoinInfoVo::getArchived).map(CodeRelateoinInfoVo::getSecurityCode).toList();
        Assert.isTrue(codes.isEmpty(), "关联的编码[" + String.join("、", codes) + "]已存档，不可删除");
        codes = relateoinInfoVos.stream().filter(CodeRelateoinInfoVo::getRegister).map(CodeRelateoinInfoVo::getSecurityCode).toList();
        Assert.isTrue(codes.isEmpty(), "关联的编码[" + String.join("、", codes) + "]已绑定用户并登记，不可删除");
        codes = relateoinInfoVos.stream().filter(CodeRelateoinInfoVo::getActiva).map(CodeRelateoinInfoVo::getSecurityCode).toList();
        Assert.isTrue(codes.isEmpty(), "关联的编码[" + String.join("、", codes) + "]已激活，不可删除");
    }

    // 根据批次编码ID删除相关编码
    @Override
    public void deleteByBatchId(Long batchId) {
        TransactionStatus status = transactionManager.getTransaction(TransactionUtil.transactionDefinition());
        try {
            List<Long> codeIds = codeMapper.getIdByBatchId(batchId);
            List<Long> codeId02s = code02Service.getIdByBatchId(batchId);
            List<Long> codeId03s = code03Service.getIdByBatchId(batchId);
            List<Long> codeId04s = code04Service.getIdByBatchId(batchId);
            List<Long> codeId05s = code05Service.getIdByBatchId(batchId);
            if (!codeIds.isEmpty()) {
                codeGoodsChangeLogService.deleteByCodeIds(codeIds);
                codeLogService.deleteByCodeIds(codeIds);
                codeInfoService.removeByIds(codeIds);
                this.removeByIds(codeIds);
            }
            if (!codeId02s.isEmpty()) {
                codeGoodsChangeLogService.deleteByCodeIds(codeId02s);
                code02Service.deleteBatchByIds(codeId02s);
            }
            if (!codeId03s.isEmpty()) {
                codeGoodsChangeLogService.deleteByCodeIds(codeId03s);
                code03Service.deleteBatchByIds(codeId03s);
            }
            if (!codeId04s.isEmpty()) {
                codeGoodsChangeLogService.deleteByCodeIds(codeId04s);
                code04Service.deleteBatchByIds(codeId04s);
            }
            if (!codeId05s.isEmpty()) {
                codeGoodsChangeLogService.deleteByCodeIds(codeId05s);
                code05Service.deleteBatchByIds(codeId05s);
            }
            transactionManager.commit(status);
        }catch (Exception e) {
            ZbManager.log.error("编码删除失败，原因提示：" + e);
            transactionManager.rollback(status);
        }
    }

    // 批量更改编码商品信息
    @Override
    @Transactional
    public void updateCodeGoods(AccounLoginInfo loginInfo, CodeBatchGoodsUpdateVo goodsUpdateVo) {
        List<Long> codeIds = goodsUpdateVo.getCodes().stream().map(CodeBatchGoodsUpdateVo.Code::getId).toList();
        checkCodeRelationInfoByIds(codeIds);
        ViewGoods newViewGoods = viewGoodsService.getByGoodsTypeAndGoodsIdAndGoodsSpecId(goodsUpdateVo.getType(), goodsUpdateVo.getGoodsId(), goodsUpdateVo.getGoodsSpecId());
        Assert.notNull(newViewGoods, "商品数据不存在");

        List<ZjCode> codeGoods = codeMapper.getGoodsByIds(codeIds);
        List<Long> goodsIds = codeGoods.stream().filter(vo -> 1 == vo.getType()).map(ZjCode::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = codeGoods.stream().filter(vo -> 1 == vo.getType()).map(ZjCode::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);
        ZjCode code = null;
        ZjCodeLog log = null;
        ZjCodeGoodsChangeLog goodsChangeLog = null;
        StringBuilder builder = new StringBuilder();
        String content = "";
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeLog> logs = new ArrayList<>();
        List<ZjCodeLog02> log02s = new ArrayList<>();
        List<ZjCodeLog03> log03s = new ArrayList<>();
        List<ZjCodeLog04> log04s = new ArrayList<>();
        List<ZjCodeLog05> log05s = new ArrayList<>();
        List<ZjCodeGoodsChangeLog> changeLogs = new ArrayList<>();
        ViewGoods oldViewGoods = null;
        for (CodeBatchGoodsUpdateVo.Code voCode : goodsUpdateVo.getCodes()) {
            code = new ZjCode();
            code.setId(voCode.getId());
            code.setType(goodsUpdateVo.getType());
            code.setGoodsId(goodsUpdateVo.getGoodsId());
            code.setGoodsSpecId(goodsUpdateVo.getGoodsSpecId());
            code.setUpdateEmpId(loginInfo.getId());
            code.setUpdateEmp(loginInfo.getName());
            oldViewGoods = codeGoods.stream().filter(cg -> Objects.equals(cg.getId(), voCode.getId())).map(cg -> {
                return viewGoodsList.stream().filter(gsv -> Objects.equals(gsv.getGoodsType(), cg.getType()) && Objects.equals(gsv.getId(), cg.getGoodsId()) && Objects.equals(gsv.getSpecId(), cg.getGoodsSpecId())).findFirst();
            }).findFirst().get().orElse(null);
            if (null == oldViewGoods) {
                builder.append(oldViewGoods.getBrand()).append(" ").append(oldViewGoods.getName()).append(" ").append(oldViewGoods.getModel()).append(" ").append(oldViewGoods.getSpecName())
                        .append(" 更改为 ")
                        .append(newViewGoods.getBrand()).append(" ").append(newViewGoods.getName()).append(" ").append(newViewGoods.getModel()).append(" ").append(newViewGoods.getSpecName());
                content = builder.toString();
                builder = builder.delete(0, builder.length());
            }
            log = new CodeLogExtend(loginInfo, CodeConstant.CODE_LOG_TYPE_1, code.getId(), "更改编码商品信息", content);

            goodsChangeLog = new ZjCodeGoodsChangeLog();
            goodsChangeLog.setId(IdWorker.getId());
            goodsChangeLog.setCustAccId(loginInfo.getCustAccId());
            goodsChangeLog.setCodeId(code.getId());
            goodsChangeLog.setType(goodsUpdateVo.getType());
            goodsChangeLog.setGoodsId(oldViewGoods.getId());
            goodsChangeLog.setGoodsSpecId(oldViewGoods.getSpecId());
            goodsChangeLog.setRemark(content);
            goodsChangeLog.setCreateEmpId(loginInfo.getId());
            goodsChangeLog.setCreateEmp(loginInfo.getName());
            if (1 == voCode.getTableType()) {
                codes.add(code);
                logs.add(log);
                changeLogs.add(goodsChangeLog);
                continue;
            }
            if (2 == voCode.getTableType()) {
                code02s.add(new ZjCode02(code));
                log02s.add(new ZjCodeLog02(log));
                changeLogs.add(goodsChangeLog);
                continue;
            }

            if (3 == voCode.getTableType()) {
                code03s.add(new ZjCode03(code));
                log03s.add(new ZjCodeLog03(log));
                changeLogs.add(goodsChangeLog);
                continue;
            }
            if (4 == voCode.getTableType()) {
                code04s.add(new ZjCode04(code));
                log04s.add(new ZjCodeLog04(log));
                changeLogs.add(goodsChangeLog);
                continue;
            }
            if (5 == voCode.getTableType()) {
                code05s.add(new ZjCode05(code));
                log05s.add(new ZjCodeLog05(log));
                changeLogs.add(goodsChangeLog);
            }
        }
        if (!codes.isEmpty()) {
            this.updateBatchById(codes);
            codeLogService.saveBatch(logs);
        }
        if (!code02s.isEmpty()) {
            code02Service.updateBatchById(code02s);
            codeLog02Service.saveBatch(log02s);
        }
        if (!code03s.isEmpty()) {
            code03Service.updateBatchById(code03s);
            codeLog03Service.saveBatch(log03s);
        }
        if (!code04s.isEmpty()) {
            code04Service.updateBatchById(code04s);
            codeLog04Service.saveBatch(log04s);
        }
        if (!code05s.isEmpty()) {
            code05Service.updateBatchById(code05s);
            codeLog05Service.saveBatch(log05s);
        }
        if (!changeLogs.isEmpty()) {
            codeGoodsChangeLogService.saveBatch(changeLogs);
        }
    }


    // 根据编码ID查询检查是否编码有关联信息
    @Override
    public void checkCodeRelationInfoByIds(List<Long> ids) {
        List<CodeRelateoinInfoVo> relateoinInfoVos = codeMapper.checkCodeRelationInfoByIds(ids);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code02Service.checkCodeRelationInfoByIds(ids);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code03Service.checkCodeRelationInfoByIds(ids);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code04Service.checkCodeRelationInfoByIds(ids);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        relateoinInfoVos = code05Service.checkCodeRelationInfoByIds(ids);
        checkCodeRelationIinfoTipMessage(relateoinInfoVos);
        List<Long> codeIds = codeMapper.getRelationWorkByIds(ids);
        if (!codeIds.isEmpty()) {
            relateoinInfoVos = codeMapper.checkCodeRelationInfoByIds(codeIds);
            List<String> codes = relateoinInfoVos.stream().filter(CodeRelateoinInfoVo::getActiva).map(CodeRelateoinInfoVo::getSecurityCode).toList();
            Assert.isTrue(codes.isEmpty(), "编码[" + String.join("、", codes) + "]已关联工单商品，不可删除");
        }
    }

    // 根据编码批次ID获取编码总数量
    @Override
    public long getCodeBatchExportTotalByBatchId(Long batchId) {
        return codeMapper.getCodeBatchExportTotalByBatchId(batchId);
    }

    // 根据批次ID分页获取编码信息
    @Override
    public List<ZjCode> getCodeBatchExportByBatchId(Long batchId, int page, int limit) {
        return codeMapper.getCodeBatchExportByBatchId(batchId, page, limit);
    }

    // 根据商品ID & 商品规格ID查询存在关联的商品ID集合
    @Override
    public List<Long> getGoodsSpecId(Integer type, Long goodsId, List<Long> goodsSpecIds) {
        return codeMapper.getGoodsSpecId(type, goodsId, goodsSpecIds);
    }

    // 根据商品ID查询存在关联的商品ID集合
    @Override
    public List<Long> getGoodsId(Integer type, List<Long> goodsIds) {
        return codeMapper.getGoodsId(type, goodsIds);
    }

    // 根据ID查询信息
    @Override
    public List<ZjCode> getRegisterByIds(List<Long> ids) {
        if (null == ids || ids.isEmpty()) {
            return new ArrayList<>();
        }
        return codeMapper.getRegisterByIds(ids);
    }

    // 保存编码登记
    @Override
    public void saveCodeRegister(CodeDataVo codeDataVo) {
        if (!codeDataVo.getCodes().isEmpty()) {
            this.updateBatchById(codeDataVo.getCodes());
            codeInfoService.updateBatchById(codeDataVo.getInfos());
            codeLogService.saveBatch(codeDataVo.getLogs());
        }
        if (!codeDataVo.getCode02s().isEmpty()) {
            code02Service.updateBatchById(codeDataVo.getCode02s());
            codeInfo02Service.updateBatchById(codeDataVo.getInfo02s());
            codeLog02Service.saveBatch(codeDataVo.getLog02s());
        }
        if (!codeDataVo.getCode03s().isEmpty()) {
            code03Service.updateBatchById(codeDataVo.getCode03s());
            codeInfo03Service.updateBatchById(codeDataVo.getInfo03s());
            codeLog03Service.saveBatch(codeDataVo.getLog03s());
        }
        if (!codeDataVo.getCode04s().isEmpty()) {
            code04Service.updateBatchById(codeDataVo.getCode04s());
            codeInfo04Service.updateBatchById(codeDataVo.getInfo04s());
            codeLog04Service.saveBatch(codeDataVo.getLog04s());
        }
        if (!codeDataVo.getCode05s().isEmpty()) {
            code05Service.updateBatchById(codeDataVo.getCode05s());
            codeInfo05Service.updateBatchById(codeDataVo.getInfo05s());
            codeLog05Service.saveBatch(codeDataVo.getLog05s());
        }
        if (!codeDataVo.getRegisters().isEmpty()) {
            codeUserRegisterService.saveBatch(codeDataVo.getRegisters());
        }
    }

    // 根据编码ID获取编码信息
    @Override
    public List<ZjCode> getSecurityCodeByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return codeMapper.getSecurityCodeByIds(ids);
    }

    // 根据编码ID获取批次编码ID
    @Override
    public List<ZjCode> getBatchIdByIds(List<Long> ids) {
        if (null == ids || ids.isEmpty()) {
            return new ArrayList<>();
        }
        return codeMapper.getBatchIdByIds(ids);
    }

    // 根据编码批次ID获取编码ID
    @Override
    public List<Long> getIdByBatchIds(List<Long> batchIds) {
        return codeMapper.getIdByBatchIds(batchIds);
    }

    // 根据批次商品表ID获取编码信息
    @Override
    public List<ZjCode> getByBatchGoodsId(Long batchGoodsId, long page, long limit) {
        return codeMapper.getByBatchGoodsId(batchGoodsId, page, limit);
    }

    // 获取未登记商品编码（成品）
    @Override
    public List<ZjCode> getNotRegisterCode(Long custAccId, OrderCodeSelectVo codeSelectVo) {
        return codeMapper.getNotRegisterCode(custAccId, codeSelectVo);
    }

    // 获取未登记商品编码总数量（成品）
    @Override
    public long getNotRegisterCodeCount(Long custAccId, OrderCodeSelectVo codeSelectVo) {
        return codeMapper.getNotRegisterCodeCount(custAccId, codeSelectVo);
    }

    // 获取已登记商品编码总数量（成品）
    @Override
    public List<CodeRegisterVo> getRegisterCode(Long custAccId, Long userId, List<Long> goodsIds, OrderCodeSelectVo codeSelectVo) {
        return codeMapper.getRegisterCode(custAccId, userId, goodsIds, codeSelectVo);
    }

    // 获取已登记商品编码总数量总记录数（成品）
    @Override
    public long getRegisterCodeCount(Long custAccId, Long userId, List<Long> goodsIds, OrderCodeSelectVo codeSelectVo) {
        return codeMapper.getRegisterCodeCount(custAccId,userId, goodsIds, codeSelectVo);
    }

    // 根据编码ID获取用户编码登记信息
    @Override
    public List<ZjCode> getUserCodeRegisterByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return codeMapper.getUserCodeRegisterByIds(ids);
    }

    // 根据编码ID获取用户编码信息
    @Override
    public ZjCode getUserCodeRegisterById(Long id) {
        return codeMapper.getUserCodeRegisterById(id);
    }

    // 根据防伪/仓库编码获取编码ID，不支持模糊查询
    @Override
    public Long getIdByCodeOrStoreCode(Long custAccId, String code) {
        return codeMapper.getIdByCodeOrStoreCode(custAccId, code);
    }

    // 根据编码ID获取商品ID
    @Override
    public ZjCode getGoodsById(Long id) {
        return codeMapper.getGoodsById(id);
    }

    // 根据编码ID获取商品编码信息
    @Override
    public List<ZjCode> getGoodsByIds(List<Long> ids) {
        return codeMapper.getGoodsByIds(ids);
    }

    // 根据防伪编码获取编码信息
    @Override
    public ZjCode getByCode(Long custAccId, String securityCode) {
        return codeMapper.getByCode(custAccId, securityCode);
    }

    // 根据编码ID获取详情
    @Override
    public CodeExtend getDetailById(Long id) {
        return codeMapper.getDetailById(id);
    }

    // 根据编码ID校验并获取存在的编码ID
    @Override
    public List<ZjCode> checkByCodes(Long custaccId, List<String> codes) {
        if (CollectionUtil.isEmpty(codes)) {
            return new ArrayList<>();
        }
        return codeMapper.checkByCodes(custaccId, codes);
    }

    // 保存出库激活一物一码
    @Override
    public void saveOutStoreActiveCode(AccounLoginInfo loginInfo, String submitType, Integer outStoreCodeActiveMode, String storeOutboundCode, Date outboundTime, List<ZjCode> codeList) {
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCodeInfo> codeInfos = new ArrayList<>();
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCodeInfo02> codeInfo02s = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCodeInfo03> codeInfo03s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCodeInfo04> codeInfo04s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeInfo05> codeInfo05s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        ZjCode code = null;
        ZjCodeInfo codeInfo = null;
        ZjCodeLog codeLog = null;
        for (ZjCode co : codeList) {
            code = new ZjCode();
            code.setId(co.getId());
            code.setStoreId(co.getStoreId());
            code.setStorePositionId(co.getStorePositionId());
            code.setStoreStatus(CodeConstant.STORE_STATUS_4);

            codeLog = new ZjCodeLog();
            codeLog.setId(IdWorker.getId());
            codeLog.setCustAccId(loginInfo.getCustAccId());
            codeLog.setCodeId(co.getId());
            codeLog.setType(CodeConstant.CODE_LOG_TYPE_1);
            codeLog.setCreateEmpId(loginInfo.getId());
            codeLog.setCreateEmp(loginInfo.getName());
            if (Objects.equals("1", submitType)) {
                codeLog.setName("出库");
                codeLog.setContent("一物一码预出库");
            }
            if (Objects.equals("2", submitType)) {
                if (Objects.equals(outStoreCodeActiveMode, SystemSetEnum.STORE_CODE_ACTIVE_MODE_1.getType())) {
                    codeLog.setName("出库");
                    codeLog.setContent("一物一码审核出库");
                }
                if (!co.getActiva() && (Objects.equals(outStoreCodeActiveMode, SystemSetEnum.STORE_CODE_ACTIVE_MODE_2.getType()) || Objects.equals(outStoreCodeActiveMode, SystemSetEnum.STORE_CODE_ACTIVE_MODE_3.getType()))) {
                    code.setActiva(true);
                    code.setOutStoreActiva(true);
                    code.setActivaTime(new Date());
                    if (Objects.equals(outStoreCodeActiveMode, SystemSetEnum.STORE_CODE_ACTIVE_MODE_3.getType())) {
                        codeLog.setName("一物一码出库激活");
                        codeLog.setContent("仓库设置：审核出库，一物一码默认激活");
                    }
                }
                if (Objects.equals(outStoreCodeActiveMode, SystemSetEnum.STORE_CODE_ACTIVE_MODE_2.getType())) {
                    code.setOutStoreWarranty(true);
                    code.setWarrantyStartTime(new Date());
                    code.setWarrantyEndTime(DateUtils.addDays(code.getWarrantyStartTime(), co.getWarrantyDay()));
                    codeLog.setName("一物一码出库激活并质保");
                    codeLog.setContent("仓库设置：出库时一物一码默认激活并质保");
                }
            }
            if (Objects.equals("3", submitType)) {
                codeLog.setName("确认出库");
                codeLog.setContent("一物一码确认出库");
            }
            codeInfo = new ZjCodeInfo();
            codeInfo.setId(co.getId());
            codeInfo.setOutboundCode(storeOutboundCode);
            codeInfo.setOutboundTime(outboundTime);

            if (0 == CodeConstant.tableType(co.getId())) {
                codes.add(code);
                codeInfos.add(codeInfo);
                codeLogs.add(codeLog);
                continue;
            }
            if (1 == CodeConstant.tableType(co.getId())) {
                code02s.add(new ZjCode02(code));
                codeInfo02s.add(new ZjCodeInfo02(codeInfo));
                codeLog02s.add(new ZjCodeLog02(codeLog));
                continue;
            }
            if (2 == CodeConstant.tableType(co.getId())) {
                code03s.add(new ZjCode03(code));
                codeInfo03s.add(new ZjCodeInfo03(codeInfo));
                codeLog03s.add(new ZjCodeLog03(codeLog));
                continue;
            }
            if (3 == CodeConstant.tableType(co.getId())) {
                code04s.add(new ZjCode04(code));
                codeInfo04s.add(new ZjCodeInfo04(codeInfo));
                codeLog04s.add(new ZjCodeLog04(codeLog));
                continue;
            }
            if (4 == CodeConstant.tableType(co.getId())) {
                code05s.add(new ZjCode05(code));
                codeInfo05s.add(new ZjCodeInfo05(codeInfo));
                codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (CollectionUtil.isNotEmpty(codes)){
            this.updateBatchById(codes);
            codeInfoService.updateBatchById(codeInfos);
            codeLogService.saveBatch(codeLogs);
        }
        if (CollectionUtil.isNotEmpty(code02s)) {
            code02Service.updateBatchById(code02s);
            codeInfo02Service.updateBatchById(codeInfo02s);
            codeLog02Service.saveBatch(codeLog02s);
        }
        if (CollectionUtil.isNotEmpty(code03s)) {
            code03Service.updateBatchById(code03s);
            codeInfo03Service.updateBatchById(codeInfo03s);
            codeLog03Service.saveBatch(codeLog03s);
        }
        if (CollectionUtil.isNotEmpty(code04s)) {
            code04Service.updateBatchById(code04s);
            codeInfo04Service.updateBatchById(codeInfo04s);
            codeLog04Service.saveBatch(codeLog04s);
        }
        if (CollectionUtil.isNotEmpty(code05s)) {
            code05Service.updateBatchById(code05s);
            codeInfo05Service.updateBatchById(codeInfo05s);
            codeLog05Service.saveBatch(codeLog05s);
        }
    }

    // 获取在库的一物一码
    @Override
    public List<ZjCode> getInStoreCodeList(Long custAccId, CodeInStoreListSearchVo searchVo) {
        return codeMapper.getInStoreCodeList(custAccId, searchVo);
    }

    // 获取在库的一物一码总记录数
    @Override
    public long getInStoreCodeListCount(Long custAccId, CodeInStoreListSearchVo searchVo) {
        return codeMapper.getInStoreCodeListCount(custAccId, searchVo);
    }

    // 更新出库激活的一物一码
    @Override
    public void updateOutStoreActiveCode(AccounLoginInfo loginInfo, boolean outStore, boolean cancelBound, List<ZjCode> updateCodeList) {
        UpdateWrapper<ZjCode> updateWrapper = null;
        UpdateWrapper<ZjCodeInfo> infoUpdateWrapper = null;
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        UpdateWrapper<ZjCode02> updateWrapper02 = null;
        UpdateWrapper<ZjCodeInfo02> infoUpdateWrapper02 = null;
        UpdateWrapper<ZjCode03> updateWrapper03 = null;
        UpdateWrapper<ZjCodeInfo03> infoUpdateWrapper03 = null;
        UpdateWrapper<ZjCode04> updateWrapper04 = null;
        UpdateWrapper<ZjCodeInfo04> infoUpdateWrapper04 = null;
        UpdateWrapper<ZjCode05> updateWrapper05 = null;
        UpdateWrapper<ZjCodeInfo05> infoUpdateWrapper05 = null;
        ZjCodeLog codeLog = null;
        for (ZjCode co : updateCodeList) {
            codeLog = new ZjCodeLog()
                    .setId(IdWorker.getId())
                    .setCustAccId(loginInfo.getCustAccId())
                    .setCodeId(co.getId())
                    .setType(CodeConstant.CODE_LOG_TYPE_1)
                    .setCreateEmpId(loginInfo.getId())
                    .setCreateEmp(loginInfo.getName());
            if (outStore) {
                codeLog.setName(cancelBound ? "作废出库单" : "驳回出库单")
                        .setContent("撒消因出库单更改的一物一码数据");
            } else {
                codeLog.setName(cancelBound ? "作废入库单" : "驳回入库单")
                        .setContent("撒消因入库单更改的一物一码数据");
            }
            if (0 == CodeConstant.tableType(co.getId())) {
                updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", co.getId());
                updateWrapper.set("store_status", co.getStoreStatus());
                updateWrapper.set("store_id", co.getStoreId());
                updateWrapper.set("store_position_id", co.getStorePositionId());
                infoUpdateWrapper = new UpdateWrapper<>();
                infoUpdateWrapper.eq("id", co.getId());
                if (outStore) {
                    updateWrapper.set("is_out_store_activa", co.getOutStoreActiva());
                    updateWrapper.set("is_out_store_warranty", co.getOutStoreWarranty());
                    updateWrapper.set("activa_time", co.getActivaTime());
                    updateWrapper.set("warranty_start_time", co.getWarrantyStartTime());
                    updateWrapper.set("warranty_end_time", co.getWarrantyStartTime());

                    infoUpdateWrapper.set("outbound_code", "");
                    infoUpdateWrapper.set("outbound_time", null);
                } else {
                    infoUpdateWrapper.set("inbound_code", "");
                    infoUpdateWrapper.set("inbound_time", null);
                }
                this.update(updateWrapper);
                codeInfoService.update(infoUpdateWrapper);
                codeLogs.add(codeLog);
                continue;
            }
            if (1 == CodeConstant.tableType(co.getId())) {
                updateWrapper02 = new UpdateWrapper<>();
                updateWrapper02.eq("id", co.getId());
                updateWrapper02.set("store_status", co.getStoreStatus());
                updateWrapper02.set("store_id", co.getStoreId());
                updateWrapper02.set("store_position_id", co.getStorePositionId());

                infoUpdateWrapper02 = new UpdateWrapper<>();
                infoUpdateWrapper02.eq("id", co.getId());
                if (outStore) {
                    updateWrapper02.set("is_out_store_activa", co.getOutStoreActiva());
                    updateWrapper02.set("is_out_store_warranty", co.getOutStoreWarranty());
                    updateWrapper02.set("activa_time", co.getActivaTime());
                    updateWrapper02.set("warranty_start_time", co.getWarrantyStartTime());
                    updateWrapper02.set("warranty_end_time", co.getWarrantyStartTime());
                    infoUpdateWrapper02.set("outbound_code", "");
                    infoUpdateWrapper02.set("outbound_time", null);
                } else {
                    infoUpdateWrapper02.set("inbound_code", "");
                    infoUpdateWrapper02.set("inbound_time", null);
                }
                code02Service.update(updateWrapper02);
                codeInfo02Service.update(infoUpdateWrapper02);
                codeLog02s.add(new ZjCodeLog02(codeLog));
                continue;
            }
            if (2 == CodeConstant.tableType(co.getId())) {
                updateWrapper03 = new UpdateWrapper<>();
                updateWrapper03.eq("id", co.getId());
                updateWrapper03.set("store_status", co.getStoreStatus());
                updateWrapper03.set("store_id", co.getStoreId());
                updateWrapper03.set("store_position_id", co.getStorePositionId());

                infoUpdateWrapper03 = new UpdateWrapper<>();
                infoUpdateWrapper03.eq("id", co.getId());
                if (outStore) {
                    updateWrapper03.set("is_out_store_activa", co.getOutStoreActiva());
                    updateWrapper03.set("is_out_store_warranty", co.getOutStoreWarranty());
                    updateWrapper03.set("activa_time", co.getActivaTime());
                    updateWrapper03.set("warranty_start_time", co.getWarrantyStartTime());
                    updateWrapper03.set("warranty_end_time", co.getWarrantyStartTime());
                    infoUpdateWrapper03.set("outbound_code", "");
                    infoUpdateWrapper03.set("outbound_time", null);
                } else {
                    infoUpdateWrapper03.set("inbound_code", "");
                    infoUpdateWrapper03.set("inbound_time", null);
                }
                code03Service.update(updateWrapper03);
                codeInfo03Service.update(infoUpdateWrapper03);
                codeLog03s.add(new ZjCodeLog03(codeLog));
                continue;
            }
            if (3 == CodeConstant.tableType(co.getId())) {
                updateWrapper04 = new UpdateWrapper<>();
                updateWrapper04.eq("id", co.getId());
                updateWrapper04.set("store_status", co.getStoreStatus());
                updateWrapper04.set("store_id", co.getStoreId());
                updateWrapper04.set("store_position_id", co.getStorePositionId());

                infoUpdateWrapper04 = new UpdateWrapper<>();
                infoUpdateWrapper04.eq("id", co.getId());
                if (outStore) {
                    updateWrapper04.set("is_out_store_activa", co.getOutStoreActiva());
                    updateWrapper04.set("is_out_store_warranty", co.getOutStoreWarranty());
                    updateWrapper04.set("activa_time", co.getActivaTime());
                    updateWrapper04.set("warranty_start_time", co.getWarrantyStartTime());
                    updateWrapper04.set("warranty_end_time", co.getWarrantyStartTime());
                    infoUpdateWrapper04.set("outbound_code", "");
                    infoUpdateWrapper04.set("outbound_time", null);
                } else {
                    infoUpdateWrapper04.set("inbound_code", "");
                    infoUpdateWrapper04.set("inbound_time", null);
                }
                code04Service.update(updateWrapper04);
                codeInfo04Service.update(infoUpdateWrapper04);
                codeLog04s.add(new ZjCodeLog04(codeLog));
                continue;
            }
            if (4 == CodeConstant.tableType(co.getId())) {
                updateWrapper05 = new UpdateWrapper<>();
                updateWrapper05.eq("id", co.getId());
                updateWrapper05.set("store_status", co.getStoreStatus());
                updateWrapper05.set("store_id", co.getStoreId());
                updateWrapper05.set("store_position_id", co.getStorePositionId());

                infoUpdateWrapper05 = new UpdateWrapper<>();
                infoUpdateWrapper05.eq("id", co.getId());
                if (outStore) {
                    updateWrapper05.set("is_out_store_activa", co.getOutStoreActiva());
                    updateWrapper05.set("is_out_store_warranty", co.getOutStoreWarranty());
                    updateWrapper05.set("activa_time", co.getActivaTime());
                    updateWrapper05.set("warranty_start_time", co.getWarrantyStartTime());
                    updateWrapper05.set("warranty_end_time", co.getWarrantyStartTime());
                    infoUpdateWrapper05.set("outbound_code", "");
                    infoUpdateWrapper05.set("outbound_time", null);
                } else {
                    infoUpdateWrapper05.set("inbound_code", "");
                    infoUpdateWrapper05.set("inbound_time", null);
                }
                code05Service.update(updateWrapper05);
                codeInfo05Service.update(infoUpdateWrapper05);
                codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (CollectionUtil.isNotEmpty(codeLogs)){
            codeLogService.saveBatch(codeLogs);
        }
        if (CollectionUtil.isNotEmpty(codeLog02s)) {
            codeLog02Service.saveBatch(codeLog02s);
        }
        if (CollectionUtil.isNotEmpty(codeLog03s)) {
            codeLog03Service.saveBatch(codeLog03s);
        }
        if (CollectionUtil.isNotEmpty(codeLog04s)) {
            codeLog04Service.saveBatch(codeLog04s);
        }
        if (CollectionUtil.isNotEmpty(codeLog05s)) {
            codeLog05Service.saveBatch(codeLog05s);
        }
    }

    // 更新一物一码入库
    @Override
    public void saveInbound(AccounLoginInfo loginInfo, String submitType, String storeInboundCode, Date inboundTime, List<ZjCode> codeList) {
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCodeInfo> codeInfos = new ArrayList<>();
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCodeInfo02> codeInfo02s = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCodeInfo03> codeInfo03s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCodeInfo04> codeInfo04s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeInfo05> codeInfo05s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        ZjCode code = null;
        ZjCodeInfo codeInfo = null;
        ZjCodeLog codeLog = null;
        for (ZjCode co : codeList) {
            code = new ZjCode();
            code.setId(co.getId());
            code.setStoreId(co.getStoreId());
            code.setStorePositionId(co.getStorePositionId());
            code.setStoreStatus(co.getStoreStatus());

            codeInfo = new ZjCodeInfo();
            codeInfo.setId(co.getId());
            codeInfo.setInboundCode(storeInboundCode);
            codeInfo.setInboundTime(inboundTime);
            codeInfo.setOutboundCode("");
            codeInfo.setOutboundTime(null);

            codeLog = new ZjCodeLog();
            codeLog.setId(IdWorker.getId());
            codeLog.setCustAccId(loginInfo.getCustAccId());
            codeLog.setCodeId(co.getId());
            codeLog.setType(CodeConstant.CODE_LOG_TYPE_1);
            codeLog.setCreateEmpId(loginInfo.getId());
            codeLog.setCreateEmp(loginInfo.getName());
            if (Objects.equals("1", submitType)) {
                codeLog.setName("保存新建入库单");
                codeLog.setContent("一物一码预入库");
            }
            if (Objects.equals("2", submitType)) {
                codeLog.setName("保存并审核入库单");
                codeLog.setContent("一物一码审核入库");
            }
            if (Objects.equals("3", submitType)) {
                codeLog.setName("确认入库");
                codeLog.setContent("一物一码确认入库");
            }
            if (0 == CodeConstant.tableType(co.getId())) {
                codes.add(code);
                codeInfos.add(codeInfo);
                codeLogs.add(codeLog);
                continue;
            }
            if (1 == CodeConstant.tableType(co.getId())) {
                code02s.add(new ZjCode02(code));
                codeInfo02s.add(new ZjCodeInfo02(codeInfo));
                codeLog02s.add(new ZjCodeLog02(codeLog));
                continue;
            }
            if (2 == CodeConstant.tableType(co.getId())) {
                code03s.add(new ZjCode03(code));
                codeInfo03s.add(new ZjCodeInfo03(codeInfo));
                codeLog03s.add(new ZjCodeLog03(codeLog));
                continue;
            }
            if (3 == CodeConstant.tableType(co.getId())) {
                code04s.add(new ZjCode04(code));
                codeInfo04s.add(new ZjCodeInfo04(codeInfo));
                codeLog04s.add(new ZjCodeLog04(codeLog));
                continue;
            }
            if (4 == CodeConstant.tableType(co.getId())) {
                code05s.add(new ZjCode05(code));
                codeInfo05s.add(new ZjCodeInfo05(codeInfo));
                codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (CollectionUtil.isNotEmpty(codes)){
            this.updateBatchById(codes);
            codeInfoService.updateBatchById(codeInfos);
            codeLogService.saveBatch(codeLogs);
        }
        if (CollectionUtil.isNotEmpty(code02s)) {
            code02Service.updateBatchById(code02s);
            codeInfo02Service.updateBatchById(codeInfo02s);
            codeLog02Service.saveBatch(codeLog02s);
        }
        if (CollectionUtil.isNotEmpty(code03s)) {
            code03Service.updateBatchById(code03s);
            codeInfo03Service.updateBatchById(codeInfo03s);
            codeLog03Service.saveBatch(codeLog03s);
        }
        if (CollectionUtil.isNotEmpty(code04s)) {
            code04Service.updateBatchById(code04s);
            codeInfo04Service.updateBatchById(codeInfo04s);
            codeLog04Service.saveBatch(codeLog04s);
        }
        if (CollectionUtil.isNotEmpty(code05s)) {
            code05Service.updateBatchById(code05s);
            codeInfo05Service.updateBatchById(codeInfo05s);
            codeLog05Service.saveBatch(codeLog05s);
        }
    }

    // 根据一物一码ID更新
    @Override
    public void updateInbound(AccounLoginInfo loginInfo, boolean outStore, Integer boundExcuteType, List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }
        UpdateWrapper<ZjCodeInfo> infoUpdateWrapper = null;
        UpdateWrapper<ZjCodeInfo02> infoUpdateWrapper02 = null;
        UpdateWrapper<ZjCodeInfo03> infoUpdateWrapper03 = null;
        UpdateWrapper<ZjCodeInfo04> infoUpdateWrapper04 = null;
        UpdateWrapper<ZjCodeInfo05> infoUpdateWrapper05 = null;
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        ZjCode code = null;
        ZjCodeInfo codeInfo = null;
        ZjCodeLog codeLog = null;
        for (Long id : ids) {
            code = new ZjCode();
            code.setId(id);
            code.setStoreId(0L);
            code.setStorePositionId(0L);
            code.setStoreStatus(CodeConstant.STORE_STATUS_1);

            codeLog = new ZjCodeLog();
            codeLog.setId(IdWorker.getId());
            codeLog.setCustAccId(loginInfo.getCustAccId());
            codeLog.setCodeId(id);
            codeLog.setType(CodeConstant.CODE_LOG_TYPE_1);
            codeLog.setCreateEmpId(loginInfo.getId());
            codeLog.setCreateEmp(loginInfo.getName());
            if (outStore) {
                codeLog.setName(boundExcuteType == 1 ? "出库物料删除" : boundExcuteType == 2 ? "出库单作废" : "出库单被驳回");
                codeLog.setContent(boundExcuteType == 1 ? "出库物料删除，一物一码的入库操作信息被撒消" : boundExcuteType == 2 ? "入库单作废，一物一码的入库操作信息被撒消" : "入库单被驳回，一物一码的入库操作信息被撒消");
            } else {
                codeLog.setName(boundExcuteType == 1 ? "入库物料删除" : boundExcuteType == 2 ? "入库单作废" : "入库单被驳回");
                codeLog.setContent(boundExcuteType == 1 ? "入库物料删除，一物一码的入库操作信息被撒消" : boundExcuteType == 2 ? "入库单作废，一物一码的入库操作信息被撒消" : "入库单被驳回，一物一码的入库操作信息被撒消");
            }
            switch (CodeConstant.tableType(id)) {
                case 0:
                    infoUpdateWrapper = new UpdateWrapper<>();
                    infoUpdateWrapper.eq("id", id);
                    if (outStore) {
                        infoUpdateWrapper.set("outbound_code", "");
                        infoUpdateWrapper.set("outbound_time", null);
                    }else {
                        infoUpdateWrapper.set("inbound_code", "");
                        infoUpdateWrapper.set("inbound_time", null);
                    }
                    codeInfoService.update(infoUpdateWrapper);
                    codes.add(code);
                    codeLogs.add(codeLog);
                    continue;
                case 1:
                    infoUpdateWrapper02 = new UpdateWrapper<>();
                    infoUpdateWrapper02.eq("id", id);
                    if (outStore) {
                        infoUpdateWrapper02.set("outbound_code", "");
                        infoUpdateWrapper02.set("outbound_time", null);
                    } else {
                        infoUpdateWrapper02.set("inbound_code", "");
                        infoUpdateWrapper02.set("inbound_time", null);
                    }
                    codeInfo02Service.update(infoUpdateWrapper02);
                    code02s.add(new ZjCode02(code));
                    codeLog02s.add(new ZjCodeLog02(codeLog));
                    continue;
                case 2:
                    infoUpdateWrapper03 = new UpdateWrapper<>();
                    infoUpdateWrapper03.eq("id", id);
                    if (outStore) {
                        infoUpdateWrapper03.set("outbound_code", "");
                        infoUpdateWrapper03.set("outbound_time", null);
                    } else {
                        infoUpdateWrapper03.set("inbound_code", "");
                        infoUpdateWrapper03.set("inbound_time", null);
                    }
                    codeInfo03Service.update(infoUpdateWrapper03);
                    code03s.add(new ZjCode03(code));
                    codeLog03s.add(new ZjCodeLog03(codeLog));
                    continue;
                case 3:
                    infoUpdateWrapper04 = new UpdateWrapper<>();
                    infoUpdateWrapper04.eq("id", id);
                    if (outStore) {
                        infoUpdateWrapper04.set("outbound_code", "");
                        infoUpdateWrapper04.set("outbound_time", null);
                    } else {
                        infoUpdateWrapper04.set("inbound_code", "");
                        infoUpdateWrapper04.set("inbound_time", null);
                    }
                    codeInfo04Service.update(infoUpdateWrapper04);
                    code04s.add(new ZjCode04(code));
                    codeLog04s.add(new ZjCodeLog04(codeLog));
                    continue;
                case 4:
                    infoUpdateWrapper05 = new UpdateWrapper<>();
                    infoUpdateWrapper05.eq("id", id);
                    if (outStore) {
                        infoUpdateWrapper05.set("outbound_code", "");
                        infoUpdateWrapper05.set("outbound_time", null);
                    } else {
                        infoUpdateWrapper05.set("inbound_code", "");
                        infoUpdateWrapper05.set("inbound_time", null);
                    }
                    codeInfo05Service.update(infoUpdateWrapper05);
                    code05s.add(new ZjCode05(code));
                    codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (CollectionUtil.isNotEmpty(codes)){
            this.updateBatchById(codes);
            codeLogService.saveBatch(codeLogs);
        }
        if (CollectionUtil.isNotEmpty(code02s)) {
            code02Service.updateBatchById(code02s);
            codeLog02Service.saveBatch(codeLog02s);
        }
        if (CollectionUtil.isNotEmpty(code03s)) {
            code03Service.updateBatchById(code03s);
            codeLog03Service.saveBatch(codeLog03s);
        }
        if (CollectionUtil.isNotEmpty(code04s)) {
            code04Service.updateBatchById(code04s);
            codeLog04Service.saveBatch(codeLog04s);
        }
        if (CollectionUtil.isNotEmpty(code05s)) {
            code05Service.updateBatchById(code05s);
            codeLog05Service.saveBatch(codeLog05s);
        }
    }

    // 获取未出入库的一物一码
    @Override
    public List<ZjCode> getStoreCodeList(Long custAccId, CodeInStoreListSearchVo searchVo) {
        return codeMapper.getStoreCodeList(custAccId, searchVo);
    }

    // 获取未出入库的一物一码总记录数
    @Override
    public long getStoreCodeListCount(Long custAccId, CodeInStoreListSearchVo searchVo) {
        return codeMapper.getStoreCodeListCount(custAccId, searchVo);
    }

    // 确认出入库后更新一物一码
    @Override
    public void updateCodeByOutInbound(AccounLoginInfo loginInfo, List<Long> codeIds, Date sendGoodsTime, boolean outStore) {
        if (CollectionUtil.isEmpty(codeIds)) {
            return;
        }
        List<ZjCode> codes = new ArrayList<>();
        List<ZjCodeInfo> codeInfos = new ArrayList<>();
        List<ZjCodeLog> codeLogs = new ArrayList<>();
        List<ZjCode02> code02s = new ArrayList<>();
        List<ZjCodeInfo02> codeInfo02s = new ArrayList<>();
        List<ZjCodeLog02> codeLog02s = new ArrayList<>();
        List<ZjCode03> code03s = new ArrayList<>();
        List<ZjCodeInfo03> codeInfo03s = new ArrayList<>();
        List<ZjCodeLog03> codeLog03s = new ArrayList<>();
        List<ZjCode04> code04s = new ArrayList<>();
        List<ZjCodeInfo04> codeInfo04s = new ArrayList<>();
        List<ZjCodeLog04> codeLog04s = new ArrayList<>();
        List<ZjCode05> code05s = new ArrayList<>();
        List<ZjCodeInfo05> codeInfo05s = new ArrayList<>();
        List<ZjCodeLog05> codeLog05s = new ArrayList<>();
        ZjCode code = null;
        ZjCodeInfo codeInfo = null;
        ZjCodeLog codeLog = null;
        for (Long id : codeIds) {
            code = new ZjCode();
            code.setId(id);
            code.setStoreStatus(outStore?CodeConstant.STORE_STATUS_5 : CodeConstant.STORE_STATUS_3);

            codeInfo = new ZjCodeInfo();
            codeInfo.setId(id);
            if (outStore) {
                codeInfo.setOutboundTime(sendGoodsTime);
            } else {
                codeInfo.setInboundTime(sendGoodsTime);
            }
            codeLog = new ZjCodeLog();
            codeLog.setId(IdWorker.getId());
            codeLog.setCustAccId(loginInfo.getCustAccId());
            codeLog.setType(CodeConstant.CODE_LOG_TYPE_1);
            codeLog.setCodeId(id);
            codeLog.setCreateEmpId(loginInfo.getId());
            codeLog.setCreateEmp(loginInfo.getName());
            codeLog.setName(outStore? "确认出库" : "确认收货");
            codeLog.setContent(outStore? "一物一码确认出库" : "一物一码确认收货");
            if (0 == CodeConstant.tableType(id)) {
                codes.add(code);
                codeInfos.add(codeInfo);
                codeLogs.add(codeLog);
                continue;
            }
            if (1 == CodeConstant.tableType(id)) {
                code02s.add(new ZjCode02(code));
                codeInfo02s.add(new ZjCodeInfo02(codeInfo));
                codeLog02s.add(new ZjCodeLog02(codeLog));
                continue;
            }
            if (2 == CodeConstant.tableType(id)) {
                code03s.add(new ZjCode03(code));
                codeInfo03s.add(new ZjCodeInfo03(codeInfo));
                codeLog03s.add(new ZjCodeLog03(codeLog));
                continue;
            }
            if (3 == CodeConstant.tableType(id)) {
                code04s.add(new ZjCode04(code));
                codeInfo04s.add(new ZjCodeInfo04(codeInfo));
                codeLog04s.add(new ZjCodeLog04(codeLog));
                continue;
            }
            if (4 == CodeConstant.tableType(id)) {
                code05s.add(new ZjCode05(code));
                codeInfo05s.add(new ZjCodeInfo05(codeInfo));
                codeLog05s.add(new ZjCodeLog05(codeLog));
            }
        }
        if (CollectionUtil.isNotEmpty(codes)){
            this.updateBatchById(codes);
            codeInfoService.updateBatchById(codeInfos);
            codeLogService.saveBatch(codeLogs);
        }
        if (CollectionUtil.isNotEmpty(code02s)) {
            code02Service.updateBatchById(code02s);
            codeInfo02Service.updateBatchById(codeInfo02s);
            codeLog02Service.saveBatch(codeLog02s);
        }
        if (CollectionUtil.isNotEmpty(code03s)) {
            code03Service.updateBatchById(code03s);
            codeInfo03Service.updateBatchById(codeInfo03s);
            codeLog03Service.saveBatch(codeLog03s);
        }
        if (CollectionUtil.isNotEmpty(code04s)) {
            code04Service.updateBatchById(code04s);
            codeInfo04Service.updateBatchById(codeInfo04s);
            codeLog04Service.saveBatch(codeLog04s);
        }
        if (CollectionUtil.isNotEmpty(code05s)) {
            code05Service.updateBatchById(code05s);
            codeInfo05Service.updateBatchById(codeInfo05s);
            codeLog05Service.saveBatch(codeLog05s);
        }
    }

    // 查询一物一码是否重复
    @Override
    public Integer existBySecurityCode(Long custAccId, String securityCode) {
        return codeMapper.existBySecurityCode(custAccId, securityCode);
    }


}
